9616. Анти
палиндромные строки
Даны два числа n и m.
Посчитайте количество строк длины n,
символы которых принадлежат алфавиту размера m, которые не содержат в качестве подстроки палиндромов длины
больше единицы.
Вход. В
первой строке записано целое число t –
количество тестов. Каждый тест представляет собой строку, в которой записано
два целых числа n и m (1 ≤ n, m ≤ 109).
Выход. Для
каждого теста выведите требуемое количество по модулю 109 + 7.
Пример
входа |
Пример
выхода |
2 5 6 6 5 |
1920 1620 |
степень
Если строка не содержат в себе
подстроку – палиндром длины 2 или длины 3, то она и не содержат в себе
подстроку – палиндром длины больше единицы.
Если n = 1, то строка длины 1 может содержать любую из m букв. Искомое число строк равно m.
Если m = 1 и n > 1, то ответ
0, так как имеется
единственная строка aa..aa и она содержит палиндром aa.
Если n = 2, то на первой позиции строки может
находиться любая из m букв, а на второй позиции – любая из m – 1 букв (буквы в первой и
второй позиции не должны совпадать, образуя палиндром). Количество искомых
строк равно (m * (m
– 1)) mod 109 + 7.
Пусть длина входной строки
больше 2. На первой позиции может находиться любая из m букв, а на второй позиции –
любая из m – 1 букв. Третья позиция должна отличаться от второй (вторая и третья
буква не должны образовывать палиндром). Третья позиция должна отличаться от
первой (первые три буквы не должны образовывать палиндром). Значит на третьей
позиции может находиться любая из m – 2 букв.
Следуя этой логике, заключаем что
буква на i-ой позиции должна отличаться от букв на позициях (i – 1) и (i – 2). Количество искомых строк равно (m
* (m – 1) * (m – 2)n –
2) mod 109 + 7.
Реализация алгоритма
Объявим
модуль, по которому будут проходить вычисления.
#define MOD
1000000007
Функция
powmod вычисляет значение xn mod m.
long long
powmod(long long x, long long n, long long m)
{
if (n ==
0) return 1;
if (n % 2
== 0) return powmod((x * x) % m, n / 2,
m);
return (x *
powmod(x, n - 1, m)) % m;
}
Основная
часть программы. Читаем входные данные.
scanf("%d", &tests);
while (tests--)
{
scanf("%lld
%lld", &n, &m);
Вычисляем
ответ в зависимости от значений n и m.
if (n
== 1) res = m; else
if (m
== 1) res = 0; else // n > 1, m =
1: aa....a
if (n
== 2) res = (m * (m - 1)) % MOD; else
res =
((m * (m - 1)) % MOD * powmod(m - 2, n - 2, MOD)) % MOD;
Выводим
ответ.
printf("%lld\n",
res);
}